
package ac.snu.street;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


import com.google.android.maps.*;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;

public class StreetPostActivity extends MapActivity{
	public static final String PREF_MAIN = "main_activity";
	public static final String KEY_MYPOST = "my_post_id";
	
	public static final int MSG_ACK_INSERT = 0;
	public static final int MSG_ACK_MODIFY = 1;
	public static final int MSG_DRAW_NOTES = 2;
	public static final int MSG_SHOW_NOTES = 3;
	

	public static RemoteDatabase remoteDB;
	private Set<String> postedIDs;
	
	final String TAG = "hji";
	private static boolean result = false;
	// for Map
	private MapView mapView;
	private MapController mapController;
	//private MapOperations mOp; 
	private GeoPoint mPoint;
	private LocationManager locationManager;
	private Location location;
	private String provider;
	private MyLocationOverlay mOverlay;
	private MyItemizedOverlay postOverlay;
	
	public StreetPostActivity(){
		mPoint = new GeoPoint(0,0);
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		startActivity(new Intent(this, SplashActivity.class));
		
		mapView = (MapView) findViewById(R.id.mapview);
        //mapView.setBuiltInZoomControls(true); 
        mapView.setSatellite(false);
        mapController = mapView.getController();
        
        mPoint = getCurrentGeoPoint();
        List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.postit);
        mOverlay = new MyLocationOverlay(this,mapView);

        //GeoPoint point = new GeoPoint((int)(location.getLatitude()*1E6),(int)(location.getLongitude()*1E6));
        OverlayPostItem overlayitem = new OverlayPostItem(0, mPoint, "Hi Pondol!", "I'm in Seoul!");
        mapOverlays.add(mOverlay);
        mOverlay.enableMyLocation();
        Log.w(TAG , "444" );
        
        setPositionCentered();
        //mapController.animateTo( point );
        //mapOverlays.add(itemizedoverlay);
        Log.w(TAG , "555" );
		remoteDB = new RemoteDatabase(mHandler);
    	
		SharedPreferences prefs = getSharedPreferences(PREF_MAIN, MODE_PRIVATE);
		postedIDs = prefs.getStringSet(KEY_MYPOST, new HashSet<String>());
	}
	
    @Override
    public void onStop() {
    	super.onStop();

    	SharedPreferences.Editor editor = getSharedPreferences(PREF_MAIN, MODE_PRIVATE).edit();
    	editor.putStringSet(KEY_MYPOST, postedIDs);    	
    	editor.commit();
    }

	//Post here button
	public void postHereClick(View view) {
		loadGps();//location 값 할당
		final LinearLayout linear = (LinearLayout) View.inflate(this,R.layout.textedit, null);
		new AlertDialog.Builder(this)
		.setTitle("What's on your mind?")
		.setIcon(R.drawable.postit)
		.setView(linear).setPositiveButton("Post", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				EditText titleView = (EditText) linear.findViewById(R.id.title);
				EditText txtView = (EditText) linear.findViewById(R.id.txt);
				
				String title = titleView.getText().toString();
				String txt = txtView.getText().toString();
				
				//GeoPoint point = getCurrentGeoPoint();
				GeoPoint centerPoint = mapView.getProjection().fromPixels(mapView.getWidth()/2, mapView.getBottom()/2);
				int latitude = centerPoint.getLatitudeE6();
				int logitude = centerPoint.getLongitudeE6();
				
				remoteDB.post(new StreetNote(latitude, logitude, title, txt));
			}
		})
		.setNegativeButton("취소", new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// Auto-generated method stub
				
			}
		})
		.show();

	}
	public void getPostNearBy(View view){
		GeoPoint centerPoint = mapView.getProjection().fromPixels(mapView.getWidth()/2, mapView.getBottom()/2);
		GeoPoint edgePoint = mapView.getProjection().fromPixels(0, 0);
		
		int latDiff = centerPoint.getLatitudeE6() - edgePoint.getLatitudeE6();
		int longDiff = centerPoint.getLongitudeE6() - edgePoint.getLongitudeE6();
		
		remoteDB.getNotesAround(centerPoint.getLatitudeE6(), centerPoint.getLongitudeE6(), (latDiff > longDiff)? latDiff : longDiff);
			
	}
	
	public void showMyPosts(View view) {
		remoteDB.getPostsById(postedIDs);
	}
	
	public void moveToMyLocation(View view){
		mPoint = getCurrentGeoPoint();
		setPositionCentered();
		mOverlay.enableMyLocation();
	}
	
	
	public Handler mHandler = new Handler() {
		@SuppressWarnings("unchecked")
		public void handleMessage(Message msg) {
			List<StreetNote> noteList;
			switch (msg.what) {
			case MSG_DRAW_NOTES:
				noteList = (List<StreetNote>) msg.obj;
				Log.d("Street", "message received! (list size: "+noteList.size()+")");
				
				int listSize = noteList.size();
				Context context = StreetPostActivity.this;
				Drawable drawable = context.getResources().getDrawable(R.drawable.postit);
				
				Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
				Drawable d = 
						new BitmapDrawable(context.getResources(), Bitmap.createScaledBitmap(bitmap,70,70,true));
				//drawable.setBounds(0, 0, 51, 56);
				
				postOverlay = new MyItemizedOverlay(d, context);
				//postOverlay = new MyItemizedOverlay(drawable, context);
				for(int i=0; i < listSize; ++i){
					GeoPoint pt = new GeoPoint(noteList.get(i).latitude, noteList.get(i).longitude);
					OverlayPostItem overlayPostItem = 
							new OverlayPostItem(noteList.get(i).id, pt, noteList.get(i).title, noteList.get(i).contents);
			        postOverlay.addOverlay(overlayPostItem);
				}
				List<Overlay> mapOverlays = mapView.getOverlays();
				mapOverlays.clear();
				mapOverlays.add(postOverlay);
				break;
				
				
			case MSG_SHOW_NOTES:
				noteList = (List<StreetNote>) msg.obj;
				Log.d("Street", "message received! (list size: "+noteList.size()+")");
				
				Intent intent = new Intent(StreetPostActivity.this, MyPostActivity.class);
				Bundle b = new Bundle();
				b.putParcelableArrayList(KEY_MYPOST, new ArrayList<StreetNote>(noteList));
				intent.putExtras(b);
				startActivity(intent);
				break;
				
				
			case MSG_ACK_INSERT:
				int postedNoteId = msg.arg1;
				Log.d("Street", "message received! (new post id: "+postedNoteId+")");
				postedIDs.add(String.valueOf(postedNoteId));
				
				getPostNearBy(null);
				break;
			case MSG_ACK_MODIFY:
				getPostNearBy(null);
			}
		}
	};

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	
	
	
	
	//////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////Map Operations /////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////
	public void setPositionCentered(){
		mapController.setCenter(mPoint);
        mapController.setZoom(15);
	}
	public GeoPoint getCurrentGeoPoint(){
		loadGps();//location 값 할당
		GeoPoint point = new GeoPoint((int)(location.getLatitude()*1E6),(int)(location.getLongitude()*1E6));
		return point;
	}
	
	  public void loadGps() {
          Log.w(TAG , "loadGps Start" );
           
          String context = Context.LOCATION_SERVICE;//안드로이드 시스템으로 부터 LocationManager 서비스를 요청하여 할당
          locationManager = (LocationManager)getSystemService(context);
          
          //GPS 환경설정
          Criteria criteria = new Criteria();
          criteria.setAccuracy(Criteria.ACCURACY_FINE);       // 정확도
          criteria.setPowerRequirement(Criteria.POWER_LOW);   // 전원 소비량
          criteria.setAltitudeRequired(false);                // 고도, 높이 값을 얻어 올지를 결정
          criteria.setBearingRequired(false);                 // provider 기본 정보
          criteria.setSpeedRequired(false);                   //속도
          criteria.setCostAllowed(true);                      //위치 정보를 얻어 오는데 들어가는 금전적 비용
           
          //상기 조건을 이용하여 알맞은 GPS선택후 위치정보를 획득
           
          //manifest xml  : <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />//로케이션 메니저의 provider
          provider = locationManager.getBestProvider(criteria, true);
          Log.i(TAG, "provider:"+provider);
          if(provider == null){//GPS 장치가 없는 휴대폰이거나 설정이 꺼져있는 경우 바로 alert 처리하거나 GPS 설정으로 이동
              result = chkGpsService();
              if(result){
                  loadGps();
              }
               
          }else{
              //location = locationManager.getLastKnownLocation(provider);//가장 최근의 로케이션을 가져온다. 안드로이드 폰이 꺼져있었거나 다른 위치로 이동한 경우 값이 없다.
              location = locationManager.getLastKnownLocation( LocationManager.NETWORK_PROVIDER );
              //이럴경우는 NETWORK_PROVIDER 로 부터 새로운 location을 지정 받는다.
              //특정조건(시간, 거리)이 되면  Listener를 invoke 시킨다.: 여기서는 1초 마다 5km)
              locationManager.requestLocationUpdates(provider, 1000, 1, loclistener);//현재정보를 업데이트
              Log.i(TAG, "location:"+location);
              if(location == null){
                  location = locationManager.getLastKnownLocation(provider);
                  if(location == null){//그래도 null인경우 alert;
                      Log.w(TAG, "get Location From GPS Fail !!!!!");
                      AlertDialog.Builder adb = new AlertDialog.Builder(StreetPostActivity.this);
                      adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                          public void onClick(DialogInterface dialog, int which) {
                          }
                      });
                     // adb.setTitle( R.string.Location_fail_title );
                      //adb.setMessage(R.string.Location_fail_message);
                      //adb.show();
                  }

              }
          }
      }  
	  private boolean chkGpsService() {//GPS의 설정여부 확인 및 자동 설정 변경
          String gs = android.provider.Settings.Secure.getString(getContentResolver(),
          android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
          Log.w("chkGpsService" , "get GPs Service" );
           
          if (gs.indexOf("gps", 0) < 0) {
              Log.w("chkGpsService" , "status: off" );
              // GPS OFF 일때 Dialog 띄워서 설정 화면으로 이동.
              AlertDialog.Builder gsDialog = new AlertDialog.Builder(this);
              gsDialog.setTitle("GPS Status OFF !!!");
              gsDialog.setMessage("Change Setting !!");
              gsDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                  public void onClick(DialogInterface dialog, int which) {
                      // GPS설정 화면으로 이동
                      Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                      intent.addCategory(Intent.CATEGORY_DEFAULT);
                      startActivity(intent);
                  }
              }).create().show();
              return false;
          } else {
              Log.w("chkGpsService" , "status: on" );                
              return true;
          }
      }     
	  private final LocationListener loclistener = new LocationListener(){
          public void onLocationChanged(Location location) {
              Log.w(TAG , "onLocationChanged" );
          }

          public void onProviderDisabled(String provider) {
              Log.w(TAG , "onProviderDisabled" );
          }

          public void onProviderEnabled(String provider) {
              Log.w(TAG , "onProviderEnabled" );
          }

          public void onStatusChanged(String provider, int status, Bundle extras) {
              Log.w(TAG , "onStatusChanged" );
          }
      };

	
}